
#include <windows.h>
//#include <tchar.h>
#include <vcclr.h>
#include "log.h"
#include "WorkerThread.h"
#include "Version.h"
#include "../ScriptHook/ScriptHookManager.h"

#include "KeyboardHook.h"


static WorkerThread _workerThread;

static HMODULE DllHandle; // original handle (GTA)
static DWORD DllThreadId; // original thread (GTA)

static HANDLE ScriptHandle; //GTAScript handle
static unsigned int ScriptThreadId; //GTAScript Thread

using namespace GTA;

unsigned int __stdcall ScriptHookManagerProlog(void*)
{
	GTA::Log::Log("GTAScript",true); // init log file
	GTA::Log::Message("--------------------");
	GTA::Log::Message("GTAScript.Net "+GTA::Version::GTAScriptVersionIdentifier);
	GTA::Log::Message("GhostGum - 2009");
	GTA::Log::Message("     -        -     ");
	GTA::Log::Message("GTAIV Script Hook "+GTA::Version::HookVersionIdentifier);
	GTA::Log::Message("Copyright (C) 2009, Aru");
	GTA::Log::Message("     -        -     ");
	GTA::Log::Message("Grand Theft Auto IV "+GTA::Version::GameVersionIdentifier);
	GTA::Log::Message("Copyright 2008, Rockstar Games");
	GTA::Log::Message("--------------------");
	if ((GTA::Version::HookVersion != 0x0401) || (GTA::Version::HookVersion > 0x0401)) GTA::Log::Warning("Unsupported ScriptHook Version! Expected: 0.4.0");
	if ((GTA::Version::GameVersion != 5) || (GTA::Version::GameVersion > 5)) GTA::Log::Warning("Unsupported GTA Version! Expected: 1.0.0.4 u5");
	
	ScriptHookManager::RegisterThread( &_workerThread );
	_workerThread.DllHandle = safe_cast<System::IntPtr>(DllHandle);
	_workerThread.DllThreadId = safe_cast<System::UInt32>(DllThreadId);




/*
	// -- test --
	WorkerThread* worker = &_workerThread;
	if (ScriptDomain::Instance == nullptr) GTA::ScriptDomain^ ScriptDomain = gcnew GTA::ScriptDomain();
	if (ScriptDomain::Instance->environmentBuilt) {worker->Scripts = ScriptDomain::Instance->scriptmanager; return 0;}
	ScriptDomain::Instance->CreateScriptDomain(); // create the actual scriptdomain that scripts will load into 
	GTA::ScriptManager^ ScriptManager = ScriptDomain::Instance->CreateScriptManager(ScriptDomain::GetScriptDomain()); 
	worker->Scripts = ScriptDomain::Instance->scriptmanager;
	ScriptManager->InitalizeHooks(worker->DllHandle,worker->DllThreadId);
	ScriptManager->OnStart();

	System::Windows::Forms::Application::Run(); // for keyboard hook (windows messages), todo: unload; (keep peeking WM, and terminate on unload)
	// -- /test--
*/

	return 0;
}

#pragma unmanaged
BOOL APIENTRY DllMain( HMODULE hModule, DWORD  fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH: 
        {
			DllHandle = hModule;
			DllThreadId = GetCurrentThreadId();

			ScriptHandle = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)&ScriptHookManagerProlog, 0, 0, (LPDWORD)&ScriptThreadId);
			if (ScriptHandle == 0 || ScriptHandle == INVALID_HANDLE_VALUE) return FALSE;
			CloseHandle(ScriptHandle);
			break;
        }
		
		case DLL_PROCESS_DETACH: 
        { // this is never called on my test machine, yet it never fails to call on my dev machine.
			_workerThread.UnloadScripts();
		}
		
    }

    return TRUE;
}







/* // exe entry point, testing
int _tmain(int argc, _TCHAR* argv[])
{
	unsigned int threadId = 0;
	HANDLE threadHandle;
	threadHandle = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)&ScriptHookManagerProlog, 0, 0, (LPDWORD)&threadId);
	if (threadHandle == 0 || threadHandle == INVALID_HANDLE_VALUE)
	{return FALSE;}
	CloseHandle(threadHandle);
	while (true)
	{
		Sleep (1000);
	}
	return 0;
}
*/

